/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Modelo.DAL;

import Modelo.*;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONObject;
import java.util.*;
import org.json.JSONArray;
import java.text.SimpleDateFormat;
import java.util.Map;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.util.JRLoader;
import java.sql.PreparedStatement;

/**
 *
 * @author Héctor Gutiérrez
 */
public class ReporteNovedad_DAO {

    //Inserta un reporte de novedad y retorna su clave.
    public static Integer insertarReporte(ReporteNovedad r,
            List<ComunidadUniversitaria> lista_implicados,
            List<EsImplicado> lista_nivel_implicados,
            List<CampoNovedad> campos) {

        ConexionBD conexion = new ConexionBD();
        PreparedStatement s = null;
        int numero_reporte;

        String query = "BEGIN; INSERT INTO reporte_novedad(agrega, "
                + "fecha_suceso, fecha_reporte,tiempo, via,descripcion,"
                + "id_novedad_generica, id_novedad_especifica)VALUES (?, current_date,"
                + " to_date(?, 'dd/mm/yyyy'),to_timestamp(?, 'HH24:MI'), ?, ?, ?, ?);";

        //INSERTA EL REPORTE  

        try {
            s = conexion.session.prepareStatement(query);
            s.setString(1, r.getAgrega());
            s.setString(2, r.getFechaSuceso());
            s.setString(3, r.getTiempo());
            s.setString(4, r.getVia());
            s.setString(5, r.getDescripcion());
            s.setInt(6, r.getId_novedad_gen());
            s.setInt(7, r.getId_novedad_esp());
            s.executeUpdate();
        } catch (SQLException se) {
            System.out.println("Error Insertando Información Básica Reporte!\n" + se.getMessage());
            return -1;
        }

        query = "SELECT MAX(id_reporte_novedad) from reporte_novedad";
        try {
            s = conexion.session.prepareStatement(query);
            ResultSet rs = s.executeQuery();
            if (!rs.next()) {
                System.out.println("Error Obteniendo el ID del último reporte!\n");
                return rollbackInsert(conexion, s);
            }
            numero_reporte = rs.getInt(1);
            System.out.println("ID Reporte: "+numero_reporte+".\n");
            rs.close();
            System.out.println(r.getPiso().length+"Longitud???");
            if (r.getPiso().length > 0) {
                for (int i = 0; i < r.getPiso().length; i++) {
                    try {
                        query = "INSERT INTO ubicacion_novedad(id_reporte_novedad, "
                                + "nombre_espacio, nombre_sede, piso)VALUES (?, ?, ?, ?)";
                        s = conexion.session.prepareStatement(query);
                        s.setInt(1, numero_reporte);
                        s.setString(2, r.getEspacio());
                        s.setString(3, r.getSede());
                        s.setInt(4, Integer.valueOf(r.getPiso()[i]));
                        s.executeUpdate();
                    } catch (SQLException se) {
                        System.out.println("Error Agregando Ubicacion Novedad con Piso! " + se.getMessage());
                        return rollbackInsert(conexion, s);
                    }
                }
            } else {
                try {
                    query = "INSERT INTO ubicacion_novedad(id_reporte_novedad, "
                            + "nombre_espacio, nombre_sede)VALUES (?, ?, ?)";
                    s = conexion.session.prepareStatement(query);
                    s.setInt(1, numero_reporte);
                    s.setString(2, r.getEspacio());
                    s.setString(3, r.getSede());
                    s.executeUpdate();
                } catch (SQLException se) {
                    System.out.println("Error Agregando Ubicacion Novedad sin Piso! " + se.getMessage());
                    return rollbackInsert(conexion, s);
                }
            }

            if (lista_implicados.size() > 0 && lista_implicados.size() == lista_nivel_implicados.size()) {
                for (int i = 0; i < lista_implicados.size(); i++) {
                    if (!Modelo.DAL.ComunidadUniversitaria_DAO.checkExistence(lista_implicados.get(i).getCi())) {
                        query = "INSERT INTO comunidad_universitaria(ci, nombre_1,"
                                + "apellido_1, telefono, email, profesion)VALUES (?, ?, ?, ?, ?, ?)";
                        try {
                            s = conexion.session.prepareStatement(query);
                            s.setString(1, lista_implicados.get(i).getCi());
                            s.setString(2, lista_implicados.get(i).getNombre1());
                            s.setString(3, lista_implicados.get(i).getApellido1());
                            s.setInt(4, lista_implicados.get(i).getTelefono());
                            s.setString(5, lista_implicados.get(i).getEmail());
                            s.setString(6, lista_implicados.get(i).getProfesion());
                            s.executeUpdate();
                            System.out.println("Persona con la CI:" + lista_implicados.get(i).getCi() + " agregada a la BD.\n");
                        } catch (SQLException se) {
                            System.out.println("Error Agregando a la persona con "
                                    + "CI:" + lista_implicados.get(i).getCi() + " en la BD.\n");
                            return rollbackInsert(conexion, s);
                        }
                    }
                    query = "INSERT INTO implicado(ci, id_reporte_novedad, tipo_implicado)VALUES (?, ?, ?)";
                    try {
                        s = conexion.session.prepareStatement(query);
                        s.setString(1, lista_implicados.get(i).getCi());
                        s.setInt(2, numero_reporte);
                        s.setString(3, lista_nivel_implicados.get(i).getTipoImplicado());
                        s.executeUpdate();
                        System.out.println("Persona con la CI:" + lista_implicados.get(i).getCi() + " agregada a la tabla de Implicados.\n");
                    } catch (SQLException se) {
                        System.out.println("Error Agregando a la persona con "
                                + "CI:" + lista_implicados.get(i).getCi() + " en la tabla de Implicados.\n"+ se.getMessage());
                        return rollbackInsert(conexion, s);
                    }
                }

            }

            for (int i = 0; campos.size() > i; i++) {
                query = "INSERT INTO informacion_reporte(id_campo_reporte,"
                        + "id_reporte, nombre_campo, valor, validacion,obligatorio)"
                        + "VALUES (?, ?, ?, ?, ?,?)";
                try {
                    s = conexion.session.prepareStatement(query);
                    s.setInt(1, Integer.parseInt(campos.get(i).getId_campo()));
                    s.setInt(2, numero_reporte);
                    s.setString(3, campos.get(i).getNombre_campo());
                    s.setString(4, campos.get(i).getValor_campo());
                    s.setInt(5, Integer.parseInt(campos.get(i).getValidacion_campo()));
                    s.setBoolean(6, Boolean.getBoolean(campos.get(i).getObligatorio_campo()));
                    s.executeUpdate();
                    System.out.println("Insertado Campo " + i + ", Nombre: " + campos.get(i).getNombre_campo() + ".\n");
                } catch (SQLException se) {
                    System.out.println("Error Insertado Campo " + i + ", Nombre: " + campos.get(i).getNombre_campo() + ".\n" + se.getMessage());
                    return rollbackInsert(conexion, s);
                }
            }
        } catch (SQLException ex) {
            System.out.println("Error Agregando Reporte Novedad! " + ex.getMessage());
            return rollbackInsert(conexion, s);
        }
        try {
            s = conexion.session.prepareStatement("COMMIT;");
            s.executeUpdate();
            System.out.println("Reporte Número " + numero_reporte + " Agregado Exitosamente!\n");
            return numero_reporte;
        } catch (SQLException ex) {
            System.out.println("Reporte Número " + numero_reporte + " no pudo ser Agregado!\n");
            return rollbackInsert(conexion, s);
        }
    }

    private static int rollbackInsert(ConexionBD conexion, PreparedStatement s) {
        try {
            System.out.println("Error Insertando Reporte!");
            s = conexion.session.prepareStatement("ROLLBACK;");
            s.executeUpdate();
            conexion.cerrarConexion();
        } catch (SQLException ex) {
            System.out.println("Error en Transaccion! " + ex.getMessage());
        }
        return -1;
    }

    public static void setPisosReporte(Integer id_reporte, String edificio, String piso, String sede) {
        ConexionBD conexion = new ConexionBD();
        Statement s = null;

        try {
            s = conexion.session.createStatement();
        } catch (SQLException se) {
            System.out.println("Error Insertando PreReporte!");
        }
        if (piso.equals("PB")) {
            piso = "0";
        }
        String query = "INSERT INTO ocurre_novedad_piso(id_reporte_novedad, id_piso, nombre_edificio,nombre_sede)"
                + "VALUES (" + id_reporte.toString() + ", " + piso + ", '" + edificio + "', '" + sede + "')";
        System.out.println("\n\tQuery: " + query + "\n");
        System.out.println(query);
        try {
            s.executeUpdate(query);
            conexion.cerrarConexion();
        } catch (SQLException se) {
            System.out.println("Error Insertando Reporte!");
            conexion.cerrarConexion();
        }
    }

    public static JSONArray consultarReportes(String limit, String offset) {
        ConexionBD conex = new ConexionBD();
        JSONArray Reportes = new JSONArray();
        PreparedStatement s = null;
        try {
            
            String query = "select r.fecha_suceso,r.fecha_reporte,g.nombre_novedad_gen,e.nombre_novedad_esp,(select count(*) from"+
                    " reporte_novedad),r.id_reporte_novedad from reporte_novedad r,novedad_generica g,novedad_especifica e"+
                    " where r.id_novedad_generica = g.id_novedad_gen and r.id_novedad_especifica = e.id_novedad_esp and"+
                    " g.id_novedad_gen = e.id_novedad_gen order by r.id_reporte_novedad desc limit ? offset ?";                    
            s = conex.session.prepareStatement(query);
            s.setInt(1,Integer.parseInt(limit));
            s.setInt(2,Integer.parseInt(offset));
            ResultSet rs = s.executeQuery();
            int i = 0;
            while (rs.next()) {
                JSONObject Reporte = new JSONObject();
                Reporte.put("fecha_suceso", rs.getString(1));
                Reporte.put("fecha_reporte", rs.getString(2));
                Reporte.put("novedad_gen", rs.getString(3));
                Reporte.put("novedad_esp", rs.getString(4));
                Reporte.put("tam", rs.getInt(5));
                Reporte.put("id_reporte", rs.getInt(6));
                Reportes.put(i, Reporte);
                i++;
            }
            rs.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            if (conex != null) {
                conex.cerrarConexion();
            }
        }
        return Reportes;
    }

    public static JSONObject getReporte(String id) {
        ConexionBD conex = new ConexionBD();
        JSONObject Reportes = new JSONObject();

        try {
            Statement st = (Statement) conex.session.createStatement();
            String query = "SELECT r.id_novedad_generica, "
                    + "g.nombre_novedad_gen, "
                    + "r.id_novedad_especifica, "
                    + "e.nombre_novedad_esp, "
                    + "r.fecha_suceso, "
                    + "r.agrega, "
                    + "c.apellido_1, "
                    + "c.nombre_1, "
                    + "r.via, "
                    + "o.nombre_sede, "
                    + "o.nombre_espacio, "
                    + "r.descripcion "
                    + "FROM reporte_novedad r "
                    + "left outer join novedad_especifica e on (e.id_novedad_esp = r.id_novedad_especifica), "
                    + "novedad_generica g, "
                    + "comunidad_universitaria c, "
                    + "ocurre_novedad_espacio o "
                    + "WHERE r.id_novedad_generica = g.id_novedad_gen AND "
                    + "c.ci = r.agrega AND "
                    + "r.id_reporte_novedad = o.id_reporte_novedad AND "
                    + "r.id_reporte_novedad = " + id;
            ResultSet rs = st.executeQuery(query);
            int i = 0;
            while (rs.next()) {
                JSONObject Reporte = new JSONObject();
                Reporte.put("id_novedad_gen", rs.getString(1).trim());
                Reporte.put("nombre_novedad_gen", rs.getString(2).trim());
                String id_novedad_esp = rs.getString(3).trim();
                if (id_novedad_esp == null) {
                    Reporte.put("id_novedad_esp", "NA");
                } else {
                    Reporte.put("id_novedad_esp", id_novedad_esp);
                }
                String nombre_novedad_esp = rs.getString(4).trim();
                if (nombre_novedad_esp == null) {
                    Reporte.put("nombre_novedad_esp", "No Aplica");
                } else {
                    Reporte.put("nombre_novedad_esp", nombre_novedad_esp);
                }
                String timestamp = rs.getString(5).trim();
                String year = timestamp.substring(0, 4);
                String month = timestamp.substring(5, 7);
                String day = timestamp.substring(8, 10);
                String fecha = day + "-" + month + "-" + year;
                String hora = timestamp.substring(11, 13);
                int hour = Integer.parseInt(hora);
                String meridiano = "AM";
                if (hour >= 12) {
                    hour -= 12;
                    meridiano = "PM";
                } else if (hour == 0) {
                    hour = 12;
                }
                if (hour < 10) {
                    hora = "0" + String.valueOf(hour);
                } else {
                    hora = String.valueOf(hour);
                }
                String minutos = timestamp.substring(14, 16);
                Reporte.put("fecha_suceso", fecha);
                Reporte.put("hora_suceso", hora);
                Reporte.put("minutos_suceso", minutos);
                Reporte.put("meridiano", meridiano);
                Reporte.put("agrega", rs.getString(6).trim());
                Reporte.put("apellido_agrega", rs.getString(7).trim());
                Reporte.put("nombre_agrega", rs.getString(8).trim());
                Reporte.put("via", rs.getString(9).trim());
                Reporte.put("sede", rs.getString(10).trim());
                Reporte.put("ubicacion", rs.getString(11).trim());
                Reporte.put("descripcion", rs.getString(12).trim());
                Reportes.put("" + i++, Reporte);
            }
            rs.close();
        } catch (Exception e) {
        } finally {
            conex.cerrarConexion();
        }
        return Reportes;
    }

    public static JSONObject getCamposDinamicos(String id) {
        ConexionBD conex = new ConexionBD();
        JSONObject Campos = new JSONObject();

        try {
            Statement st = (Statement) conex.session.createStatement();
            ResultSet rs;
            int i;
            JSONObject Campo;
            String query1 = "SELECT p.id_campo_novedad, "
                    + "c.nombre, "
                    + "p.valor "
                    + "FROM   posee p, "
                    + "campo_novedad c "
                    + "WHERE  p.id_campo_novedad = c.id_campo_novedad AND "
                    + "p.id_reporte = " + id;
            rs = st.executeQuery(query1);
            i = 0;
            while (rs.next()) {
                Campo = new JSONObject();
                Campo.put("id_campo_novedad", rs.getString(1).trim());
                Campo.put("nombre_campo", rs.getString(2).trim());
                Campo.put("valor", rs.getString(3).trim());
                Campos.put("" + i++, Campo);
            }
            String query2 = "SELECT t.id_campo_novedad, "
                    + "c.nombre, "
                    + "t.valor "
                    + "FROM   tiene t, "
                    + "campo_novedad c "
                    + "WHERE  t.id_campo_novedad = c.id_campo_novedad AND "
                    + "t.id_reporte = " + id;
            rs = st.executeQuery(query2);
            while (rs.next()) {
                Campo = new JSONObject();
                Campo.put("id_campo_novedad", rs.getString(1).trim());
                Campo.put("nombre_campo", rs.getString(2).trim());
                Campo.put("valor", rs.getString(3).trim());
                Campos.put("" + i++, Campo);
            }
            rs.close();
        } catch (Exception e) {
        } finally {
            conex.cerrarConexion();
        }
        return Campos;
    }

    public static void actualizarReporte(ReporteNovedad rep) {
        ConexionBD conexion = new ConexionBD();
        Statement s = null;

        try {
            s = conexion.session.createStatement();
        } catch (SQLException se) {
            System.out.println("Error Actualizando Reporte!");
        }
        String query = "UPDATE reporte_novedad "
                + "set agrega = '" + rep.getAgrega()
                + "', fecha_suceso = '" + rep.getFechaSuceso()
                + "', descripcion = '" + rep.getDescripcion()
                + "' where id_reporte_novedad = " + rep.getIdReporteNovedad().toString();
        System.out.println("\n\tQuery: " + query + "\n");
        System.out.println(query);

        try {
            s.executeUpdate(query);
        } catch (SQLException se) {
            System.out.println("Error Insertando Pre-Reporte!");
        } finally {
            conexion.cerrarConexion();
        }
    }

    public static void updateEspacioReporte(String id_reporte, String espacio, String sede, String[] pisos) {
        ConexionBD conexion = new ConexionBD();
        Statement s = null;

        try {
            s = conexion.session.createStatement();
        } catch (SQLException se) {
            System.out.println("Error Actualizando Reporte!");
        }
        String query = "UPDATE ocurre_novedad_espacio "
                + "set nombre_espacio = '" + espacio
                + "', nombre_sede = '" + sede
                + "' where id_reporte_novedad = " + id_reporte;
        System.out.println("\n\tQuery: " + query + "\n");
        System.out.println(query);
        String query2 = "DELETE FROM ocurre_novedad_piso "
                + " where id_reporte_novedad = " + id_reporte;
        System.out.println("\n\tQuery: " + query2 + "\n");
        System.out.println(query2);
        try {
            s.executeUpdate(query);
            s.executeUpdate(query2);
            if (pisos != null) {
                for (int i = 0; i < pisos.length; i++) {
                    setPisosReporte(Integer.parseInt(id_reporte), espacio, pisos[i], sede);
                }
            }
        } catch (SQLException se) {
            System.out.println("Error Actualizando Espacio de Reporte!");
        } finally {
            conexion.cerrarConexion();
        }
    }

    public byte[] generarReporte(Map parametros) {
        ConexionBD conexion = new ConexionBD();
        byte[] pdf = null;
        String filename = "/Modulo1/informeNovedad.jasper";
        JasperReport masterReport = null;
        try {
            masterReport = (JasperReport) JRLoader.loadObject(getClass().getResource(filename));
            //String ruta = masterReport.getMainDataset().getParameters()[18].getDefaultValueExpression().getChunks()[0].getText();
            pdf = JasperRunManager.runReportToPdf(masterReport, parametros, conexion.session);
        } catch (JRException e) {
            e.printStackTrace();
        }
        if (conexion.session != null) {
            conexion.cerrarConexion();
        }

        return pdf;
    }

    public static List<Integer> getOcurrenciasAlarmas(int id_gen, int id_esp) {
        // Este arreglo tendrá: ocurrencias totales ng, ocurrencias a corto plazo ng,
        // ocurrencias totales ne, ocurrencias a corto plazo ne, alerta general ng,
        // alerta cp ng, alerta general ne y alerta cp ne
        ConexionBD conex = new ConexionBD();
        Statement s = null;
        List<Integer> ocurrencias_alarmas = new ArrayList<Integer>();
        String id_ng = String.valueOf(id_gen);
        String id_ne = String.valueOf(id_esp);
        try {
            Statement st = (Statement) conex.session.createStatement();
            SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Calendar cal = Calendar.getInstance();
            String fecha_hoy = formato.format(cal.getTime());
            String fecha_ant = formato.format((cal.getTimeInMillis()) - 432000000);
            String query;
            if (id_esp != -1) {
                query = "SELECT (select count(*) from reporte_novedad where id_novedad_generica = " + id_ng + "), "
                        + "(select count(*) from reporte_novedad where id_novedad_especifica = " + id_ne + "), "
                        + "(select count(*) from reporte_novedad where (fecha_reporte >='" + fecha_ant + "' and fecha_reporte <= '" + fecha_ant + "') and id_novedad_generica = " + id_ng + "), "
                        + "(select count(*) from reporte_novedad where (fecha_reporte >='" + fecha_ant + "' and fecha_reporte <= '" + fecha_ant + "') and id_novedad_especifica = " + id_ne + "), "
                        + "g.alerta_gen, "
                        + "g.alerta_cp, "
                        + "e.alerta_gen, "
                        + "e.alerta_cp "
                        + "FROM   novedad_generica g, "
                        + "novedad_especifica e "
                        + "WHERE  g.id_novedad_gen = e.id_novedad_gen AND "
                        + "g.id_novedad_gen = " + id_ng + " AND "
                        + "e.id_novedad_esp = " + id_ne;
            } else {
                query = "SELECT (select count(*) from reporte_novedad where id_novedad_generica = " + id_ng + "), "
                        + "(select count(*) from reporte_novedad where (fecha_reporte >='" + fecha_ant + "' and fecha_reporte <= '" + fecha_ant + "') and id_novedad_generica = " + id_ng + "), "
                        + "g.alerta_gen, "
                        + "g.alerta_cp "
                        + "FROM   novedad_generica g "
                        + "WHERE g.id_novedad_gen = " + id_ng;
            }
            ResultSet rs = st.executeQuery(query);
            while (rs.next()) {
                if (id_esp != -1) {
                    for (int i = 1; i <= 8; i++) {
                        ocurrencias_alarmas.add(rs.getInt(i));
                    }
                } else {
                    for (int i = 1; i <= 4; i++) {
                        ocurrencias_alarmas.add(rs.getInt(i));
                    }
                }
            }
            rs.close();
        } catch (Exception e) {
        } finally {
            if (conex != null) {
                conex.cerrarConexion();
            }
        }
        return ocurrencias_alarmas;
    }
}
